//
//  CSMACAInitiator.hpp
//  WiFiMACSim
//
//  Created by Christopher Kemsley on 4/1/12.
//  Copyright (c) 2012 iAppolopolis. All rights reserved.
//

#ifndef WiFiMACSim_CSMACAInitiator_hpp
#define WiFiMACSim_CSMACAInitiator_hpp

#include "Node.hpp"
#include "Settings.hpp"
#include "Message.hpp"
#include "Medium.hpp"
#include "Statistics.hpp" 
#include <stdlib.h>
#include "Statistics.hpp"


SimNamespaceBegin



class	CSMACAInitiator : public StateMachineNode<CSMACAInitiator>
{
public:
	enum {
		idle = 0,				//Transmitter waiting for for packet to be sent from upper layers
		checkMed = 1,			//If transmitter receives packet to be sent it will check medium
		waitToSend = 2,			//Waiting for medium to become idle to send
		waitDIFS = 3,			//DIFS period
		waitPauseDIFS = 4,		//Pauses if transmission occurs during DIFS period while waiting to send
		sendData = 5,			
		waitACK = 6,
		packetCollision = 7,
		backoff = 8			//Backoff period
	} ;
	
	ID const	target ;
	
	UInteger	lambdaScalar ;
	UInteger	createDIFS;
	UInteger	createTraffic;
	UInteger	createBackoff;
	UInteger	createTimeout;
	Message*	message ;
	StateStat	statistics ;
	
	CSMACAInitiator ( ID const & name , ID const & inTarget , UInteger inLambdaScalar = 1 ) ;
	virtual ~CSMACAInitiator ();
	
	void	update_idle						( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_checkMed					( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_waitToSend				( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_waitDIFS					( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_waitPauseDIFS			( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_sendData					( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_waitACK					( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_packetCollision			( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	void	update_backoff					( UInteger currentTime , Medium::MsgSet const & currentReception ) ;
	
	int getMultiplier						(bool selection) ;
} ;




SimNamespaceEnd
#endif
